<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    title="选择员工"
    width="50%"
    @ok="handleSubmit"
    @cancel="handleClose"
    @open-change="handleVisibleChange"
  >
    <div class="page-main">
      <div class="left">
        <BasicTree
          search
          show-icon
          defaultExpandAll
          treeWrapperClassName="h--[calc(100vh-500px)] overflow-auto"
          :clickRowToExpand="false"
          :treeData="treeData"
          v-model:selectedKeys="selectedKeys"
          :fieldNames="{ key: 'id', title: 'name' }"
          @select="handleSelect"
          ref="asyncExpandTreeRef"
        >
          <template #icon="{ level }">
            <img :src="level_1" v-if="[0, 1].includes(level)" />
            <img :src="level_3" v-else-if="level === 2" />
          </template>
        </BasicTree>
      </div>
      <div class="mid">
        <div class="mid-top">
          <div>
            <a-input
              placeholder="请输入名称"
              v-model:value="searchText"
              allowClear
              @change="handleSearchChange"
            >
              <template #prefix>
                <img :src="searchIcon" style="width: 14px" />
              </template>
            </a-input>
          </div>
          <div class="check-box" @click="clickCheckAll">
            <span>全选</span>
            <div> <img :src="checkedAllSrc" /> </div
          ></div>
        </div>
        <div class="overscroll-box">
          <template v-if="selectDeptId || searchAllUser">
            <div class="person-box" v-if="userList.length">
              <div
                class="item"
                v-for="item in userList"
                :key="item.userId"
                @click="setItemChecked(item)"
              >
                <span>{{ onlyreadCheck === 'user' ? item.name : item.roleName }}</span>
                <div class="check-box">
                  <img :src="getItemChecked(item)" />
                </div>
              </div>
            </div>
            <div class="no-data" v-else>暂无数据</div>
          </template>
          <div class="no-data" v-else>请先选择左侧部门！</div>
        </div>
        <div class="mid-bottom">
          <div class="check-item" @click="onlyread('user')">
            <div>
              <img :src="onlyreadCheck === 'user' ? checked : checkEmpty" />
            </div>
            <span>只看用户</span>
          </div>
          <div class="check-item" style="cursor: default"> </div>
          <!-- <div class="check-item" @click="onlyread('role')">
            <div>
              <img :src="onlyreadCheck === 'user' ? checkEmpty : checked" />
            </div>
            <span>只看角色</span>
          </div> -->
          <div class="check-item" @click="handleSearchAll">
            <div>
              <img :src="searchAllUser ? checked : checkEmpty" />
            </div>
            <span>查询所有用户</span>
          </div>
          <div class="check-item" @click="handleByName">
            <div>
              <img :src="byName ? checked : checkEmpty" />
            </div>
            <span>按名称排名</span>
          </div>
        </div>
      </div>
      <div class="right">
        <div class="top" v-if="selectedUsers.length">
          <div class="item" v-for="item in selectedUsers" :key="item.userId">
            <span>{{ onlyreadCheck === 'user' ? item.name : item.roleName }}</span>
            <div class="close-btn" @click="deleteUser(item)">
              <img :src="closeImg" />
            </div>
          </div>
        </div>
        <div v-else class="please-choose-person"
          >请选择{{ onlyreadCheck === 'user' ? '用户' : '角色' }}！</div
        >
        <div class="bottom">
          <div class="bottom-left">
            已选
            <span style="color: rgba(43, 99, 161, 1)">{{ selectedUsers.length }}</span
            >个{{ onlyreadCheck === 'user' ? '用户' : '角色' }}
          </div>
          <div @click="clearAllSelected" class="clear-all">清空</div>
        </div>
      </div>
    </div>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { ref, computed, unref, nextTick } from 'vue';
  import searchIcon from '/@/assets/images/search-icon.png';
  import checkEmpty from '/@/assets/images/check-empty.png';
  import checked from '/@/assets/images/checked.png';
  import indeterminate from '/@/assets/images/indeterminate.png';
  import level_1 from '/@/assets/images/choose-person-level-1.png';
  import level_3 from '/@/assets/images/choose-person-level-3.png';
  import closeImg from '/@/assets/images/close-blue.png';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { TreeDataItem } from 'ant-design-vue/es/tree/Tree';
  import { BasicTree, TreeActionType } from '/@/components/Tree';
  import { debounce, cloneDeep } from 'lodash-es';

  import { getAddressList, getAddressUserList } from '/@/api/admin/userDept';
  import { AddressUserListParams } from '/@/api/admin/model/systemModel';

  import { useMessage } from '/@/hooks/web/useMessage';

  const { createMessage } = useMessage();

  const treeData = ref<Array<TreeDataItem>>([]);
  const userList = ref<Array<any>>([]);
  const selectedUsers = ref<Array<any>>([]);
  const onlyreadCheck = ref('user');
  const searchAllUser = ref(false);
  const selectDeptId = ref('');
  const byName = ref(false);
  const asyncExpandTreeRef = ref<Nullable<TreeActionType>>(null);
  const searchText = ref('');
  const selectedKeys = ref([]);

  const checkedAllSrc = computed(() => {
    if (!userList.value.length) return checkEmpty;
    const checkedMap: boolean[] = [];
    userList.value.forEach((item) => {
      const find = getFindItem(item);
      checkedMap.push(find ? true : false);
    });
    const allChecked = checkedMap.every((item) => item);
    const allUnChecked = checkedMap.every((item) => !item);
    return allChecked ? checked : allUnChecked ? checkEmpty : indeterminate;
  });

  const emit = defineEmits(['success', 'register', 'cancel']);

  const [registerDrawer, { setModalProps }] = useModalInner(async (data) => {
    selectedUsers.value = data && (data.userList ? cloneDeep(data.userList) : []);
    setModalProps({ confirmLoading: false });
  });

  function getFindItem(item, type = 'find') {
    return selectedUsers.value[type]((user) => {
      if (hasProperty(user, 'roleId')) return user.roleId == item.roleId;
      return user.userId == item.userId;
    });
  }

  function handleSubmit() {
    emit('success', selectedUsers.value);
  }

  function handleClose() {
    emit('cancel');
  }

  function arrayFlagLevel(array, level) {
    if (!array || !array.length) return;
    array.forEach((item) => {
      item.level = level;
      if (item.children && item.children.length) {
        arrayFlagLevel(item.children, level + 1);
      }
    });
  }

  function setItemChecked(item) {
    const findIndex = getFindItem(item, 'findIndex');
    if (findIndex > -1) {
      selectedUsers.value.splice(findIndex, 1);
    } else {
      if (selectedUsers.value.length >= 10) {
        createMessage.warn('最多选择10个岗位人员！');
      } else {
        selectedUsers.value.push(item);
      }
    }
  }

  function hasProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }

  function getItemChecked(item) {
    const find = getFindItem(item);
    return find ? checked : checkEmpty;
  }

  async function commonRequest(deptId = '') {
    const params: AddressUserListParams = {
      deptId,
      addressType: 0,
      name: searchText.value,
    };
    if (byName.value) {
      params.nameSort = 0;
    }
    const res = await getAddressUserList(params);
    userList.value = onlyreadCheck.value === 'user' ? res.list : res.roleVOS;
  }

  function handleSelect(key) {
    searchAllUser.value = false;
    selectDeptId.value = key[0];
    if (!key[0]) return;
    commonRequest(key[0]);
  }

  const handleSearchChange = debounce(() => {
    searchText.value = searchText.value.trim();
    if (!selectDeptId.value && !searchAllUser.value) return;
    const deptId = searchAllUser.value ? '' : selectDeptId.value;
    commonRequest(deptId);
  }, 500);

  function getTree() {
    const tree = unref(asyncExpandTreeRef);
    if (!tree) {
      throw new Error('tree is null!');
    }
    return tree;
  }

  function handleSearchAll() {
    searchAllUser.value = !searchAllUser.value;
    if (searchAllUser.value) {
      selectDeptId.value = '';
      getTree().setSelectedKeys([]);
      commonRequest();
    }
  }

  function deleteUser(item) {
    const findIndex = getFindItem(item, 'findIndex');
    selectedUsers.value.splice(findIndex, 1);
  }

  function handleByName() {
    byName.value = !byName.value;
    if (!selectDeptId.value && !searchAllUser.value) return;
    const deptId = searchAllUser.value ? '' : selectDeptId.value;
    commonRequest(deptId);
  }

  async function onlyread(type) {
    if (onlyreadCheck.value != type) {
      onlyreadCheck.value = type;
      selectedUsers.value = [];
    }
    if (!selectDeptId.value && !searchAllUser.value) return;
    const deptId = searchAllUser.value ? '' : selectDeptId.value;
    commonRequest(deptId);
  }

  async function getAddressListFn(name = '') {
    const data = await getAddressList({
      name,
      addressType: 0,
    });
    arrayFlagLevel(data, 0);
    treeData.value = data;
    nextTick(() => {
      unref(asyncExpandTreeRef)?.expandAll(true);
    });
  }

  function clickCheckAll() {
    if ([indeterminate, checkEmpty].includes(checkedAllSrc.value)) {
      try {
        userList.value.forEach((item) => {
          if (selectedUsers.value.length >= 10) throw 'max';
          const find = getFindItem(item);
          if (!find) selectedUsers.value.push(item);
        });
      } catch (res) {
        if (res === 'max') createMessage.warn('最多选择10个岗位人员！');
      }
    } else {
      userList.value.forEach((item) => {
        const findIndex = getFindItem(item, 'findIndex');
        if (findIndex > -1) selectedUsers.value.splice(findIndex, 1);
      });
    }
  }

  function clearAllSelected() {
    selectedUsers.value = [];
  }

  async function handleVisibleChange(visible) {
    if (visible) {
      await getAddressListFn();
      searchAllUser.value = false;
      selectDeptId.value = '';
      onlyreadCheck.value = 'user';
      userList.value = [];
    } else {
      selectedKeys.value = [];
    }
  }
</script>

<style scoped lang="less">
  .page-main {
    border-radius: 2px 2px 2px 2px;
    border: 1px solid #e9e9e9;
    display: flex;
    max-height: calc(100vh - 435px);

    .left {
      flex: 1;
      border-right: 1px solid #e9e9e9;
      padding: 12px;
      overflow-y: auto;

      .tree-box {
        margin-top: 8px;
      }
    }

    .mid {
      flex: 1;
      border-right: 1px solid #e9e9e9;
      display: flex;
      flex-direction: column;
      justify-content: space-between;

      &-top {
        display: flex;
        justify-content: space-between;
        margin-bottom: 18px;
        padding: 12px 12px 0 8px;

        .check-box {
          display: flex;
          align-items: center;
          cursor: pointer;
          user-select: none;

          span {
            margin-right: 8px;
          }
        }
      }

      .overscroll-box {
        flex: 1;
        // height: 400px;
        overflow-y: auto;

        .person-box {
          cursor: pointer;
          padding: 0 12px;
          user-select: none;

          .item {
            display: flex;
            justify-content: space-between;
            // padding: 9px 0 9px 4px;
            min-height: 32px;
            align-items: center;
            margin-bottom: 8px;

            span {
              flex: 1;
              margin-right: 8px;
            }
          }
        }

        .no-data {
          height: 100%;
          width: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
        }
      }

      &-bottom {
        display: flex;
        flex-wrap: wrap;

        width: 100%;

        .check-item {
          height: 36px;
          width: 50%;
          display: flex;
          align-items: center;
          padding: 12px;
          cursor: pointer;
          user-select: none;

          &:nth-child(1) {
            border: 1px solid #e9e9e9;
            border-left: none;
          }

          &:nth-child(2) {
            border: 1px solid #e9e9e9;
            border-left: none;
            border-right: none;
          }

          &:nth-child(3) {
            border-right: 1px solid #e9e9e9;
          }

          div {
            margin-right: 8px;
          }
        }
      }
    }

    .right {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-between;

      .top {
        flex: 1;
        overflow-y: auto;
        padding: 12px 12px 0 12px;

        .item {
          height: 32px;
          padding: 9px 12px;
          background: rgba(43, 99, 161, 0.05);
          border-radius: 2px 2px 2px 2px;
          border: 1px solid rgba(43, 99, 161, 0.3);
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: 8px;

          .close-btn {
            cursor: pointer;
          }

          span {
            color: rgba(43, 99, 161, 1);
          }
        }
      }

      .please-choose-person {
        flex: 1;
        display: flex;
        justify-content: center;
        align-items: center;
        padding-top: 25px;
      }

      .bottom {
        display: flex;
        height: 37px;
        border-top: 1px solid #e9e9e9;
        justify-content: space-between;
        align-items: center;
        padding: 12px;
        color: rgba(43, 99, 161, 1);

        .bottom-left {
          color: #999999;
        }

        .clear-all {
          cursor: pointer;
        }
      }
    }
  }

  ::v-deep(.vben-tree-header) {
    border-bottom: none;
    padding: 0 0 10px 0;
  }

  ::v-deep(.HChooseUser-tag) {
    &.ant-select-disabled {
      .ant-select-selector {
        cursor: pointer !important;
        background: @component-background !important;

        input,
        .ant-select-selection-item {
          cursor: pointer !important;
        }
      }
    }
  }
</style>
